#include "../include/head.h"

void *download_enter(void *arg)
{
    printf("进入子线程！\n");
    // 与服务端建立tcp连接
    int download_sockfd=socket(AF_INET,SOCK_STREAM,0);
    struct sockaddr_in addr;
    bzero(&addr,sizeof(addr));
    addr.sin_family=AF_INET;
    addr.sin_addr.s_addr=inet_addr("127.0.0.1");
    addr.sin_port=htons(30000);
    int ret=connect(download_sockfd,(struct sockaddr*)&addr,sizeof(addr));
    ERROR_CHECK(ret,-1,"connect");

    // 从share里获取对应数据
    shareRes_t *share = (shareRes_t*)arg;

    char argbuf[1024]={0};
    memcpy(argbuf,share->agrs,share->args_len);
    char *addr1=strtok(argbuf," ");//客户端文件的地址
    char *addr2=strtok(NULL," ");//服务端要存储的文件的地址
    char *netfilesizebuf=strtok(NULL," ");
    char* md5 = strtok(NULL," ");
    // 多传来三个
    char *father_netfd = strtok(NULL, " ");
    char *user_id = strtok(NULL, " ");
    char *now_path_id = strtok(NULL, " ");

    off_t netfilesize = 0;
    sscanf(netfilesizebuf,"%ld",&netfilesize);

    char *filename;
    char *fileFatherPath;
    split_path(addr1,&fileFatherPath,&filename);

    char localFilePath[512] = {0}; 
    if(addr2[strlen(addr2)-1]=='/')
    {
        sprintf(localFilePath,"%s%s",addr2,filename);
    }
    else
    {
        sprintf(localFilePath,"%s/%s",addr2,filename);
    }

    off_t filesize = share->file_size;

    int open_fd = 0;

    if(share->client_choose == 2)
    {
        int type = C_OP_GETS_BEGIN;
        char sendargs[1024]={0};
        filesize = filesize - (filesize % 4096);
        sprintf(sendargs,"%s %s %ld %s %s %s %s",addr1,addr2,filesize,md5,father_netfd,user_id,now_path_id);
        int sendargs_len = strlen(sendargs);
        send(download_sockfd,&type,sizeof(int),MSG_NOSIGNAL);
        send(download_sockfd,&sendargs_len,sizeof(int),MSG_NOSIGNAL);
        send(download_sockfd,sendargs,sendargs_len,MSG_NOSIGNAL);
        open_fd = open(localFilePath,O_RDWR);
        lseek(open_fd,filesize,SEEK_SET);
    }
    else if(share->client_choose == 1)
    {
        
        int type = C_OP_GETS_BEGIN;
        char sendargs[1024]={0};
        filesize = 0;
        sprintf(sendargs,"%s %s %ld %s %s %s %s",addr1,addr2,filesize,md5,father_netfd,user_id,now_path_id);
        int sendargs_len = strlen(sendargs);
        send(download_sockfd,&type,sizeof(int),MSG_NOSIGNAL);
        send(download_sockfd,&sendargs_len,sizeof(int),MSG_NOSIGNAL);
        send(download_sockfd,sendargs,sendargs_len,MSG_NOSIGNAL);
        open_fd = open(localFilePath,O_RDWR|O_TRUNC);
        lseek(open_fd,0,SEEK_SET);
    }
    else if(share->client_choose == 9)
    {
        open_fd = open(localFilePath,O_CREAT|O_RDWR,0666);
        int type = C_OP_GETS_BEGIN;
        char sendargs[1024]={0};
        filesize = 0;
        sprintf(sendargs,"%s %s %ld %s %s %s %s",addr1,addr2,filesize,md5,father_netfd,user_id,now_path_id);
        int sendargs_len = strlen(sendargs);
        send(download_sockfd,&type,sizeof(int),MSG_NOSIGNAL);
        send(download_sockfd,&sendargs_len,sizeof(int),MSG_NOSIGNAL);
        send(download_sockfd,sendargs,sendargs_len,MSG_NOSIGNAL);
        lseek(open_fd,0,SEEK_SET);

    }

    long processed = filesize;
    //long max_size = (long)512*1024*1024;
    char recvbuf[4096]={0};
    while(processed<netfilesize)
    {
        bzero(recvbuf,4096);
        int recvsize = recv(download_sockfd,recvbuf,4096,0);
        if(recvsize ==0)
        {
            break;
        }
        write(open_fd,recvbuf,recvsize);
        processed+=recvsize;
    }

    close(open_fd);
    free(filename);
    free(fileFatherPath);
    

    close(download_sockfd);
    free(share);
    printf("下载任务已完成！\n");
    pthread_exit(NULL);

}

void*upload_enter(void*arg)
{
    printf("进入子线程！\n");
    // 与服务端建立tcp连接
    int netfd = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in addr;
    bzero(&addr,sizeof(addr));
    addr.sin_family=AF_INET;
    addr.sin_addr.s_addr=inet_addr("127.0.0.1");
    addr.sin_port=htons(30000);
    int ret=connect(netfd,(struct sockaddr*)&addr,sizeof(addr));
    ERROR_CHECK(ret,-1,"connect");

    // 从shere里获取对应数据
    shareRes_t *share = (shareRes_t*)arg;

    char argbuf[2048]={0};
    memcpy(argbuf,share->agrs,share->args_len);
    char *addr1=strtok(argbuf," ");//客户端文件的地址
    char *addr2=strtok(NULL," ");//服务端要存储的文件的地址
    char *md5=strtok(NULL," ");
    char *filesizebuf=strtok(NULL," ");
    char *father_netfd = strtok(NULL, " ");
    char *user_id = strtok(NULL, " ");
    char *now_path_id = strtok(NULL, " ");

    off_t netfilesize = 0;
    sscanf(filesizebuf,"%ld",&netfilesize);

    if (share->client_choose == 1)
    {
        char sendargs[2048] = {0};
        sprintf(sendargs, "%s %ld", share->agrs, share->file_size);
        int sendargs_len = strlen(sendargs);
        int sendtype = C_OP_PUTS_BEGIN;
        send(netfd, &sendtype, sizeof(int), MSG_NOSIGNAL);
        send(netfd, &sendargs_len, sizeof(int), MSG_NOSIGNAL);
        send(netfd, sendargs, strlen(sendargs), MSG_NOSIGNAL);
    }
    else if(share->client_choose == 2)
    {
        char sendargs[1024]={0};
        netfilesize = 0;
        sprintf(sendargs,"%s %s %s %ld %s %s %s %ld",addr1,addr2,md5,netfilesize,father_netfd,user_id,now_path_id,share->file_size);
        int sendargs_len = strlen(sendargs);
        int sendtype = C_OP_PUTS_BEGIN;
        send(netfd,&sendtype,sizeof(int),MSG_NOSIGNAL);
        send(netfd,&sendargs_len,sizeof(int),MSG_NOSIGNAL);
        send(netfd,sendargs,strlen(sendargs),MSG_NOSIGNAL);
    }
    else if(share->client_choose == 3)
    {
        char sendargs[2048]={0};
        sprintf(sendargs,"%s %ld",share->agrs,share->file_size);
        // printf("子线程sendargs = %s\n", sendargs);
        int sendargs_len = strlen(sendargs);
        // printf("sendargslen = %d\n", sendargs_len);
        int sendtype = C_OP_PUTS_BEGIN;
        send(netfd,&sendtype,sizeof(int),MSG_NOSIGNAL);
        send(netfd,&sendargs_len,sizeof(int),MSG_NOSIGNAL);
        send(netfd,sendargs,sendargs_len,MSG_NOSIGNAL);
    }

    int open_fd = open(addr1,O_RDWR);
    lseek(open_fd,netfilesize,SEEK_SET);

    long processed = netfilesize;
    // long max_size = (long)2*1024*1024*1024;
    long max_size = (long)512*1024*1024;//512M
    while(processed<share->file_size)
    {
        long sendsize = share->file_size - processed > (max_size)?max_size:share->file_size - processed;
        char* p = (char*)mmap(NULL,sendsize,PROT_READ|PROT_WRITE,MAP_SHARED,open_fd,processed);
        send(netfd,(void*)p,sendsize,MSG_NOSIGNAL);
        munmap(p,sendsize);
        processed+=sendsize;
        // printf("%ld/%ld\n",processed,share->file_size);
    }

    close(open_fd);
    printf("上传任务已完成！\n");

    close(netfd);
    free(share);

    pthread_exit(NULL);

    // // 建立监听集合
    // int upload_epfd=epoll_create(1);
    // epollAdd(upload_epfd, upload_sockfd,0);

    // struct epoll_event readySet[1024]={0};

    // RequestPackage *requestPackage = (RequestPackage *)malloc(sizeof(RequestPackage));
    // ResponsePackage *responsePackage = (ResponsePackage*)malloc(sizeof(ResponsePackage));
    // bzero(requestPackage,sizeof(ResponsePackage));
    // bzero(responsePackage,sizeof(ResponsePackage));

    // while(1)
    // {
    //     int ready_num = epoll_wait(upload_epfd, readySet, 1024, -1);
    //     for (int i = 0; i < ready_num;i++)
    //     {
    //         if(readySet[i].data.fd == upload_sockfd)
    //         {
    //              // 从服务端接受包
    //             bzero(responsePackage,sizeof(ResponsePackage));
    //             recvn(upload_sockfd, &responsePackage->type, sizeof(int), NULL);
    //             if(ret == -1)
    //             {
    //                     printf("服务端已断开链接！\n");
    //                     goto end;
    //             }
    //             recvn(upload_sockfd, &responsePackage->args_len, sizeof(int), NULL);
    //             if(ret == -1)
    //             {
    //                     printf("服务端已断开链接！\n");
    //                     goto end;
    //             }
    //             if(responsePackage->args_len!=0)
    //             {
    //                 recvn(upload_sockfd, &responsePackage->args_val, responsePackage->args_len, NULL);
    //                 if(ret == -1)
    //                 {
    //                     printf("服务端已断开链接！\n");
    //                     goto end;
    //                 }
    //             }

    //             // type解析器
    //             if(responsePackage->type == 1)
    //             {

    //             }
    //             else if(responsePackage->type == 2)
    //             {

    //             }

    //         }

    //     }
    // }
    // end:
 
  
    }